using System.Web.Services;
using System.Xml;
using System;
using log4net;

namespace umlungu.engineX.scorecardX {
	/// <summary>
	/// umlungu scorecardX web services
	/// </summary>
	[WebService(Namespace="http://www.umlungu.com/engineX/")]
	public class scorecardX : x_result {
		#region Private properties
		private x_config config;
		private x_scorecard scorecardx;
		#endregion

		#region Visible properties
		/// <summary>The host server</summary>
		/// <value>The name of the host server</value>
		public string Host {
			get { return config.Value("ScorecardX/@host"); }
		}
		/// <summary>The path to the application on the host</summary>
		/// <value>The path (or '' if the root application)</value>
		public string Path {
			get { return config.Value("ScorecardX/@path"); }
		}
		/// <summary>The directory containing the data</summary>
		/// <value>The name of the data directory</value>
		public string Data {
			get { return config.Value("ScorecardX/@data"); }
		}
		/// <summary>The default template</summary>
		/// <value>The name of the default template file (in the data directory)</value>
		public string Default {
			get { return config.Value("ScorecardX/template[@name='default']"); }
		}
		/// <summary>The default template file</summary>
		/// <value>The name of the default template file (including path to the data directory and extension)</value>
		public string DataFileName {
			get { return String.Concat(scorecardx.BaseDirectory, "\\", scorecardx.DataDirectory, "\\", Default, ".xml"); }
		}
		#endregion

		#region Constructors/Destructors
		/// <summary>Constructor</summary>
		public scorecardX() : base("X", "ScorecardX") {
			config = new x_config();
			scorecardx = new x_scorecard();
			scorecardx.BaseDirectory = Server.MapPath(".");
			scorecardx.DataDirectory = Data;
			scorecardx.Acquire(DataFileName, true);
		}
		#endregion

		#region Web service methods
		/// <summary>
		/// Tests the web service
		/// </summary>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description="Tests the web service")] 
		public XmlDocument TestScoreCardX() {
			try {
				AddOk();
				AddNode(scorecardx);
				return Result;
			} 
			catch(System.Exception e) 	{_AddError(e); return(Result);}
		}
		#endregion

		#region Card Web service methods
		/// <summary>Gets the defauly scorecard case</summary>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Gets the default Card (the template)")]
		public XmlDocument GetDefault() {
			try {
				AddOk();
				AddNode(scorecardx.GetTemplate());
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		#endregion

		#region Card Web service methods
		/// <summary>Lists the scorecard cases in the system</summary>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Lists the Cards available")]
		public XmlDocument ListCards() {
			try {
				AddOk();
				XmlElement cards = AddElem("cards", "");
				foreach(XmlNode card in scorecardx.ListCards()) {
					AddNode(cards, "card", (card as XmlElement).GetAttribute("name"));
				}
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}
		
		/// <summary>Creates a new scorecard case</summary>
		/// <param name="FileName">The name of the file within the data path</param>
		/// <param name="CardName">The name of the case within the case file</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description="Creates a new Card")] 
		public XmlDocument NewCard(string FileName, string CardName) {
			try {
				AddOk();
				scorecardx.NewCard(CardName, FileName);
				scorecardx.SaveCards(DataFileName);
				AddNode(scorecardx);
				return Result;
			} 
			catch(System.Exception e) 	{_AddError(e); return(Result);}
		}

		/// <summary>Adds new scorecard case to an existing one</summary>
		/// <param name="CardName">The name of the case within the case file</param>
		/// <param name="NewCardName">The name of the new case</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Adds a new Card (from an existing one)")]
		public XmlDocument AddCard(string CardName, string NewCardName) {
			try {
				AddOk();
				scorecardx.AddCard(CardName, NewCardName);
				scorecardx.SaveCards(DataFileName);
				AddNode(scorecardx);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Gets a scorecard case (expands if neccassary)</summary>
		/// <param name="CardName">The name of the case within the case file</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Gets a Card (expands if neccassary)")]
		public XmlDocument GetCard(string CardName) {
			try {
				AddOk();
				AddNode(scorecardx.GetCard(CardName).OuterXml);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Removes an existing scorecard case</summary>
		/// <param name="CardName">The name of the case within the case file</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Removes an existing Card")]
		public XmlDocument DeleteCard(string CardName) {
			try {
				AddOk();
				scorecardx.DeleteCard(CardName);
				scorecardx.SaveCards(DataFileName);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Updates an existing scorecard case</summary>
		/// <param name="CardName">The name of the case within the case file</param>
		/// <param name="CardXml">The replacement xml</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Updates an existing Card")]
		public XmlDocument UpdateCard(string CardName, string CardXml) {
			try {
				AddOk();
				scorecardx.UpdateCard(CardName, CardXml);
				scorecardx.SaveCards(DataFileName);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Loads and then save the scorecard</summary>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Saves all cards")]
		public XmlDocument SaveCards() {
			try {
				AddOk();
				scorecardx.SaveCards(DataFileName, true);
				AddNode(scorecardx);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Loads and then save a scorecard case</summary>
		/// <param name="CardName">The name of the case within the case file</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Saves a card")]
		public XmlDocument SaveCard(string CardName) {
			try {
				AddOk();
				scorecardx.GetCard(CardName);
				scorecardx.SaveCards(DataFileName, CardName);
				AddNode(scorecardx);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		#endregion

		#region Card property Web service methods
		/// <summary>Adds a property to a scorecard case</summary>
		/// <param name="CardName">The name of the case</param>
		/// <param name="PropertyName">The name of the new property</param>
		/// <param name="PropertyLabel">A descriptive label for the property</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Adds a new Card property")]
		public XmlDocument AddProperty(string CardName, string PropertyName, string PropertyLabel) {
			try {
				AddOk();
				scorecardx.AddProperty(CardName, PropertyName, PropertyLabel);
				scorecardx.SaveCards(DataFileName);
				AddNode(scorecardx);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Removes a property from the scorecard case</summary>
		/// <param name="CardName">The name of the case</param>
		/// <param name="PropertyName">The name of the new property</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Removes a Card property")]
		public XmlDocument DeleteProperty(string CardName, string PropertyName) {
			try {
				AddOk();
				scorecardx.DeleteProperty(CardName, PropertyName);
				scorecardx.SaveCards(DataFileName);
				AddNode(scorecardx);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Adds a property value to a scorecard case</summary>
		/// <param name="CardName">The name of the case</param>
		/// <param name="PropertyName">The name of the new property</param>
		/// <param name="PropertyValue">A property value</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Adds a new Card property value")]
		public XmlDocument AddPropertyValue(string CardName, string PropertyName, string PropertyValue) {
			try {
				AddOk();
				scorecardx.AddPropertyValue(CardName, PropertyName, PropertyValue);
				scorecardx.SaveCards(DataFileName);
				AddNode(scorecardx);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Clears all values from a property in the scorecard case</summary>
		/// <param name="CardName">The name of the case</param>
		/// <param name="PropertyName">The name of the new property</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Clears values from a Card property")]
		public XmlDocument ClearProperty(string CardName, string PropertyName) {
			try {
				AddOk();
				scorecardx.ClearProperty(CardName, PropertyName);
				scorecardx.SaveCards(DataFileName);
				AddNode(scorecardx);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Gets a property in the scorecard case</summary>
		/// <param name="CardName">The name of the case</param>
		/// <param name="PropertyName">The name of the new property</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Gets a Card property")]
		public XmlDocument GetProperty(string CardName, string PropertyName) {
			try {
				AddOk();
				AddNode(scorecardx.GetProperty(CardName, PropertyName));
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Gets the properties in the scorecard case</summary>
		/// <param name="CardName">The name of the case</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Gets the Card properties")]
		public XmlDocument GetProperties(string CardName) {
			try {
				AddOk();
				XmlNode props = AddNode("properties", "");
				foreach (XmlNode prop in scorecardx.GetProperties(CardName)) {
					props.AppendChild(Result.ImportNode(prop, true));
				}
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		#endregion

		#region Score Web service methods
		/// <summary>Gets a score in a scorecard case</summary>
		/// <param name="CardName">The name of the case</param>
		/// <param name="ScoreName">The name of the new score</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Gets a score")]
		public XmlDocument GetScore(string CardName, string ScoreName) {
			try {
				AddOk();
				AddNode(scorecardx.GetScore(CardName, ScoreName).OuterXml);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Adds a score to a scorecard case</summary>
		/// <param name="CardName">The name of the case</param>
		/// <param name="GroupName">The name of the case group</param>
		/// <param name="ScoreName">The name of the new score</param>
		/// <param name="ScoreLabel">A descriptive label for the score</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Adds a new score")]
		public XmlDocument AddScore(string CardName, string GroupName, string ScoreName, string ScoreLabel) {
			try {
				AddOk();
				XmlNode newscore = scorecardx.AddScore(CardName, GroupName, ScoreName, ScoreLabel);
				scorecardx.SaveCards(DataFileName);
				AddNode(newscore.OuterXml);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Removes a score from the scorecard case</summary>
		/// <param name="CardName">The name of the case</param>
		/// <param name="ScoreName">The name of the new score</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Removes a score")]
		public XmlDocument DeleteScore(string CardName, string ScoreName) {
			try {
				AddOk();
				scorecardx.DeleteScore(CardName, ScoreName);
				scorecardx.SaveCards(DataFileName);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Adds a value  to a score in a scorecard case</summary>
		/// <param name="CardName">The name of the case</param>
		/// <param name="ScoreName">The name of the new score</param>
		/// <param name="ScoreValue">The value of the score</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Adds a score value")]
		public XmlDocument AddScoreValue(string CardName, string ScoreName, string ScoreValue) {
			try {
				AddOk();
				AddNode(scorecardx.AddScoreValue(CardName, ScoreName, ScoreValue).OuterXml);
				scorecardx.SaveCards(DataFileName);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}
		
		/// <summary>Adds a weight  to a score in a scorecard case</summary>
		/// <param name="CardName">The name of the case</param>
		/// <param name="ScoreName">The name of the new score</param>
		/// <param name="ScoreWeight">The weight of the score</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Adds a score weight")]
		public XmlDocument AddScoreWeight(string CardName, string ScoreName, string ScoreWeight) {
			try {
				AddOk();
				AddNode(scorecardx.AddScoreWeight(CardName, ScoreName, ScoreWeight).OuterXml);
				scorecardx.SaveCards(DataFileName);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Adds a value  to a score in a scorecard case</summary>
		/// <param name="CardName">The name of the case</param>
		/// <param name="ScoreName">The name of the new score</param>
		/// <param name="ScoreValue">The value of the score</param>
		/// <param name="ScoreWeight">The weight of the score</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Adds a score value and weight")]
		public XmlDocument AddScoreValueWeight(string CardName, string ScoreName, string ScoreValue, string ScoreWeight) {
			try {
				AddOk();
				AddNode(scorecardx.AddScoreValue(CardName, ScoreName, ScoreValue, ScoreWeight).OuterXml);
				scorecardx.SaveCards(DataFileName);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		#endregion

		#region ScoreSet Web service methods
		/// <summary>Lists the scorecard sets in a scorecard case</summary>
		/// <param name="CardName">The name of the case within the case file</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Lists the ScoreSets in a Card")]
		public XmlDocument ListSets(string CardName) {
			try {
				AddOk();
				XmlElement sets = AddElem("scores", "");
				foreach (XmlNode set in scorecardx.ListSets(CardName)) {
					//XmlElement setel = AddNode(sets, "score", (set as XmlElement).GetAttribute("name")) as XmlElement;
					XmlElement setel = AddNode(sets, "score", "") as XmlElement;
					foreach (XmlAttribute att in set.Attributes) {
						setel.SetAttribute(att.Name, att.Value);
					}
				}
				return Result;
			} catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Checks a scorecard set exists in an existing scorecard case</summary>
		/// <param name="CardName">The name of the case within the case file</param>
		/// <param name="SetName">The name of the set within the case</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Checks a ScoreSet exists in a Card")]
		public XmlDocument CheckSet(string CardName, string SetName) {
			try {
				AddOk();
				scorecardx.CheckSet(CardName, SetName);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Gets the scorecard sets in an existing scorecard case</summary>
		/// <param name="CardName">The name of the case within the case file</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Gets the ScoreSets in a Card")]
		public XmlDocument GetSets(string CardName) {
			try {
				AddOk();
				AddNode(scorecardx.GetSets(CardName));
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Gets a scorecard set in an existing scorecard case</summary>
		/// <param name="CardName">The name of the case within the case file</param>
		/// <param name="SetName">The name of the set within the case</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Gets a ScoreSet in a Card")]
		public XmlDocument GetSet(string CardName, string SetName) {
			try {
				AddOk();
				AddNode(scorecardx.GetSet(CardName, SetName));
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Adds new, blank scorecard set to an existing scorecard case</summary>
		/// <param name="CardName">The name of the case within the case file</param>
		/// <param name="SetName">The name of the set within the case</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Adds a new, blank ScoreSet (to an card)")]
		public XmlDocument NewSet(string CardName, string SetName) {
			try {
				AddOk();
				AddNode(scorecardx.AddSet(CardName, SetName));
				scorecardx.SaveCards(DataFileName, CardName);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Adds new scorecard set to an existing scorecard case</summary>
		/// <param name="CardName">The name of the case within the case file</param>
		/// <param name="SetName">The name of the set within the case</param>
		/// <param name="SetXml">The score xml</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Adds a new ScoreSet (to an card)")]
		public XmlDocument AddSet(string CardName, string SetName, string SetXml) {
			try {
				AddOk();
				scorecardx.AddSet(CardName, SetName, SetXml);
				scorecardx.SaveCards(DataFileName, CardName);
				AddNode(scorecardx);
				return Result;
			} catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Updates a scorecard set in an existing scorecard case</summary>
		/// <param name="CardName">The name of the case within the case file</param>
		/// <param name="SetName">The name of the set within the case</param>
		/// <param name="Status">The status of the set within the case</param>
		/// <param name="SetXml">The scoreset xml</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Updates an existing ScoreSet (in an card)")]
		public XmlDocument UpdateSet(string CardName, string SetName, string Status, string SetXml) {
			try {
				AddOk();
				AddNode(scorecardx.UpdateSet(CardName, SetName, Status, SetXml));
				scorecardx.SaveCards(DataFileName, CardName);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Removes a scorecard set from an existing scorecard case</summary>
		/// <param name="CardName">The name of the case within the case file</param>
		/// <param name="SetName">The name of the set within the case</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Removes a ScoreSet from a card")]
		public XmlDocument DeleteSet(string CardName, string SetName) {
			try {
				AddOk();
				AddNode(scorecardx.DeleteSet(CardName, SetName));
				scorecardx.SaveCards(DataFileName, CardName);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Removes a property from the scorecard set</summary>
		/// <param name="CardName">The name of the case</param>
		/// <param name="SetName">The name of the set within the case</param>
		/// <param name="PropertyName">The name of the new property</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Removes a Set property")]
		public XmlDocument DeleteSetProperty(string CardName, string SetName, string PropertyName) {
			try {
				AddOk();
				scorecardx.DeleteProperty(CardName, SetName, PropertyName);
				scorecardx.SaveCards(DataFileName, CardName);
				AddNode(scorecardx);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Gets a property in the scorecard set</summary>
		/// <param name="CardName">The name of the case</param>
		/// <param name="SetName">The name of the set within the case</param>
		/// <param name="PropertyName">The name of the new property</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Gets a Set property")]
		public XmlDocument GetSetProperty(string CardName, string SetName, string PropertyName) {
			try {
				AddOk();
				AddNode(PropertyName, scorecardx.GetProperty(CardName, SetName, PropertyName));
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		/// <summary>Gets a list of values of a property in the scorecard set</summary>
		/// <param name="CardName">The name of the case</param>
		/// <param name="SetName">The name of the set within the case</param>
		/// <param name="PropertyName">The name of the new property</param>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Gets a Set property list")]
		public XmlDocument GetSetProperties(string CardName, string SetName, string PropertyName) {
			try {
				AddOk();
				AddNode(PropertyName, scorecardx.GetProperties(CardName, SetName, PropertyName));
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		#endregion

		#region Utility Web service methods
		/// <summary>Clears the id attributes from all nodes (assumes loaded)</summary>
		/// <returns>Returns an XmlDocument</returns>
		[WebMethod(Description = "Clears the id attributes from all scores")]
		public XmlDocument ClearID() {
			try {
				AddOk();
				scorecardx.RemoveIDs();
				scorecardx.SaveCards(DataFileName);
				AddNode(scorecardx);
				return Result;
			}
			catch (System.Exception e) { _AddError(e); return (Result); }
		}

		#endregion
	}
}
